// Process Management (进程管理) 示例
// 演示 Pascal 中进程管理的各种用法
program p_40_process_management;

{$mode objfpc}{$H+}
// {$mode objfpc} 启用 Object Pascal 模式
// {$H+} 启用长字符串支持（AnsiString）

// 引入单元文件
uses
  SysUtils,      // 系统工具单元
  Classes,       // 类单元
  Process;       // 进程管理单元

// 显示进程信息的过程
procedure DisplayProcessInfo(Process: TProcess);
begin
  WriteLn('  进程信息:');
  WriteLn('    可执行文件: ', Process.Executable);
  WriteLn('    参数数量: ', Process.Parameters.Count);
  if Process.Parameters.Count > 0 then
  begin
    Write('    参数列表: ');
    for var i := 0 to Process.Parameters.Count - 1 do
      Write(Process.Parameters[i], ' ');
    WriteLn;
  end;
end;

// 执行简单命令的示例
procedure SimpleCommandExecution;
var
  process: TProcess;
  outputLines: TStringList;
begin
  WriteLn('1. 简单命令执行:');
  process := TProcess.Create(nil);
  outputLines := TStringList.Create;
  try
    {$IFDEF WINDOWS}
      process.Executable := 'cmd.exe';
      process.Parameters.Add('/c');
      process.Parameters.Add('echo Hello from Pascal Process Management!');
    {$ELSE}
      process.Executable := 'echo';
      process.Parameters.Add('Hello from Pascal Process Management!');
    {$ENDIF}
    
    // 设置选项
    process.Options := [poWaitOnExit, poUsePipes];
    
    DisplayProcessInfo(process);
    
    // 执行进程
    process.Execute;
    
    // 读取输出
    outputLines.LoadFromStream(process.Output);
    
    WriteLn('  命令输出:');
    for var i := 0 to outputLines.Count - 1 do
      WriteLn('    ', outputLines[i]);
    
    WriteLn('  进程退出代码: ', process.ExitStatus);
  finally
    outputLines.Free;
    process.Free;
  end;
end;

// 执行系统信息命令的示例
procedure SystemInfoCommandExecution;
var
  process: TProcess;
  outputLines: TStringList;
begin
  WriteLn('2. 系统信息命令执行:');
  process := TProcess.Create(nil);
  outputLines := TStringList.Create;
  try
    {$IFDEF WINDOWS}
      process.Executable := 'cmd.exe';
      process.Parameters.Add('/c');
      process.Parameters.Add('ver');
    {$ELSE}
      process.Executable := 'uname';
      process.Parameters.Add('-a');
    {$ENDIF}
    
    // 设置选项
    process.Options := [poWaitOnExit, poUsePipes];
    
    DisplayProcessInfo(process);
    
    // 执行进程
    process.Execute;
    
    // 读取输出
    outputLines.LoadFromStream(process.Output);
    
    WriteLn('  系统信息:');
    for var i := 0 to outputLines.Count - 1 do
      WriteLn('    ', outputLines[i]);
    
    WriteLn('  进程退出代码: ', process.ExitStatus);
  finally
    outputLines.Free;
    process.Free;
  end;
end;

// 带输入的进程执行示例
procedure ProcessWithInput;
var
  process: TProcess;
  inputStream: TMemoryStream;
  outputStream: TStringList;
  inputText: String = 'Hello, Process Input!';
begin
  WriteLn('3. 带输入的进程执行:');
  process := TProcess.Create(nil);
  inputStream := TMemoryStream.Create;
  outputStream := TStringList.Create;
  try
    {$IFDEF WINDOWS}
      process.Executable := 'more';
    {$ELSE}
      process.Executable := 'cat';
    {$ENDIF}
    
    // 设置选项
    process.Options := [poWaitOnExit, poUsePipes];
    
    DisplayProcessInfo(process);
    
    // 准备输入数据
    inputStream.WriteAnsiString(inputText);
    inputStream.Position := 0;
    
    // 执行进程
    process.Execute;
    
    // 写入输入数据
    inputStream.SaveToStream(process.Input);
    process.CloseInput;
    
    // 读取输出
    outputStream.LoadFromStream(process.Output);
    
    WriteLn('  输入文本: ', inputText);
    WriteLn('  输出结果:');
    for var i := 0 to outputStream.Count - 1 do
      WriteLn('    ', outputStream[i]);
    
    WriteLn('  进程退出代码: ', process.ExitStatus);
  finally
    outputStream.Free;
    inputStream.Free;
    process.Free;
  end;
end;

// 进程超时控制示例
procedure ProcessWithTimeout;
var
  process: TProcess;
  startTime, endTime: QWord;
begin
  WriteLn('4. 进程超时控制:');
  process := TProcess.Create(nil);
  try
    {$IFDEF WINDOWS}
      process.Executable := 'ping';
      process.Parameters.Add('127.0.0.1');
      process.Parameters.Add('-n');
      process.Parameters.Add('5');  // 发送5个ping包
    {$ELSE}
      process.Executable := 'ping';
      process.Parameters.Add('-c');
      process.Parameters.Add('5');  // 发送5个ping包
      process.Parameters.Add('127.0.0.1');
    {$ENDIF}
    
    // 设置选项
    process.Options := [poWaitOnExit, poUsePipes];
    
    DisplayProcessInfo(process);
    
    startTime := GetTickCount64;
    WriteLn('  开始执行进程...');
    
    // 执行进程
    process.Execute;
    
    endTime := GetTickCount64;
    WriteLn('  进程执行时间: ', (endTime - startTime), ' 毫秒');
    WriteLn('  进程退出代码: ', process.ExitStatus);
  finally
    process.Free;
  end;
end;

// 进程环境变量设置示例
procedure ProcessWithEnvironment;
var
  process: TProcess;
  outputLines: TStringList;
begin
  WriteLn('5. 进程环境变量设置:');
  process := TProcess.Create(nil);
  outputLines := TStringList.Create;
  try
    {$IFDEF WINDOWS}
      process.Executable := 'cmd.exe';
      process.Parameters.Add('/c');
      process.Parameters.Add('echo PATH = %PATH%');
    {$ELSE}
      process.Executable := 'printenv';
      process.Parameters.Add('PATH');
    {$ENDIF}
    
    // 设置选项
    process.Options := [poWaitOnExit, poUsePipes];
    
    // 设置环境变量
    process.Environment.Add('MY_CUSTOM_VAR=Hello from Pascal');
    
    DisplayProcessInfo(process);
    
    // 执行进程
    process.Execute;
    
    // 读取输出
    outputLines.LoadFromStream(process.Output);
    
    WriteLn('  环境变量输出:');
    for var i := 0 to outputLines.Count - 1 do
      WriteLn('    ', outputLines[i]);
    
    WriteLn('  进程退出代码: ', process.ExitStatus);
  finally
    outputLines.Free;
    process.Free;
  end;
end;

// 程序主入口
begin
  WriteLn('=== Pascal 进程管理示例 ===');
  WriteLn;
  
  // 1. 简单命令执行
  SimpleCommandExecution;
  
  WriteLn;
  
  // 2. 系统信息命令执行
  SystemInfoCommandExecution;
  
  WriteLn;
  
  // 3. 带输入的进程执行
  ProcessWithInput;
  
  WriteLn;
  
  // 4. 进程超时控制
  ProcessWithTimeout;
  
  WriteLn;
  
  // 5. 进程环境变量设置
  ProcessWithEnvironment;
  
  WriteLn;
  WriteLn('演示了 Pascal 中进程管理的各种用法');
  
  // 等待用户按键，防止程序窗口立即关闭
  ReadLn;
end.